package com.xhwl.data.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhwl.common.dto.cent.business.RoomCompanyDTO;
import com.xhwl.common.dto.cent.sdata.RoomAreaCountDTO;
import com.xhwl.common.dto.cent.sdata.RoomDTO;
import com.xhwl.common.dto.cent.sdata.space.ErrorSpace;
import com.xhwl.common.dto.cent.sdata.space.RentRoomPicDTO;
import com.xhwl.common.enums.OperationTypeEnum;
import com.xhwl.common.enums.OrganizationTypeEnum;
import com.xhwl.common.enums.RoomTypeEnum;
import com.xhwl.common.enums.space.ViewType;
import com.xhwl.common.exception.DataException;
import com.xhwl.common.pojo.AbstractSpace;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.*;
import com.xhwl.common.query.cent.sdata.OrganizationQuery;
import com.xhwl.common.query.cent.sdata.RoomQuery;
import com.xhwl.common.utils.StringUtils;
import com.xhwl.data.dao.IFloorDao;
import com.xhwl.data.dao.IOrganizationDao;
import com.xhwl.data.dao.IRoomDao;
import com.xhwl.data.event.SpaceUpdateEvent;
import com.xhwl.data.mq.producer.OrganizationProducer;
import com.xhwl.data.pojo.annotation.OrganizationHandle;
import com.xhwl.data.pojo.space.RoomCheck;
import com.xhwl.data.pojo.space.RoomOperateDTO;
import com.xhwl.common.pojo.cent.sdata.space.RoomOperateLog;
import com.xhwl.data.service.*;
import com.xhwl.data.util.AutoCodeUtils;
import com.xhwl.data.util.CodePrefixConstant;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author: luyi
 * @Description:
 * @Date: Create in 18:04 2021/1/21
 */
@Service
public class RoomServiceImpl extends ServiceImpl<IRoomDao, Room> implements IRoomService {

    @Autowired
    private IRoomDao roomDao;

    @Autowired
    private IOrganizationDao organizationDao;

    @Autowired
    private IFloorDao floorDao;

    @Autowired
    private IOrganizationService organizationService;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private IOrganizationTypeService organizationTypeService;

    @Autowired
    private IProjectService projectService;

    @Autowired
    private IRoomOperatorLogService roomOperatorLogService;

    private final static Logger log = LoggerFactory.getLogger(RoomServiceImpl.class);

    @Autowired
    private OrganizationProducer organizationProducer;
    @Override
    @Transactional
    @OrganizationHandle(operationType = OperationTypeEnum.CREATE)
    //@SpaceFunctionTypeHandle(organizationTypeEnum = OrganizationTypeEnum.ROOM,operationType = OperationTypeEnum.CREATE)
    public ResultJson create(RoomDTO roomDTO) {
        Room room = new Room();
        BeanUtils.copyProperties(roomDTO, room);
        room.setIsDelete(false);
        roomDao.insert(room);
        roomDTO.setId(room.getId());
        // 生成编码
        if (StringUtils.isEmpty(room.getCode())) {
            String code = AutoCodeUtils.codeFormat(CodePrefixConstant.ROOM_PREFIX, room.getId(), CodePrefixConstant.CODE_LENGTH);
            room.setCode(code);
            roomDao.updateById(room);
        }
        Organization org = organizationService.getById(roomDTO.getOrganizationId());
        org.setCode(room.getCode());
        if (null !=room.getFunctionType()){
            org.setFunctionType(room.getFunctionType());
        }
        organizationService.update(org);
        Organization parent = organizationService.getById(roomDTO.getParentId());

        RoomDTO roomDTO1 = new RoomDTO();
        BeanUtils.copyProperties(room, roomDTO1);
        roomDTO1.setFullName(getFullName(room.getOrganizationId()));
        AbstractSpace space = roomDTO1;
        space.setSpaceType(OrganizationTypeEnum.ROOM);
        SpaceUpdateEvent spaceUpdateEvent = new SpaceUpdateEvent(this, space, parent.getProjectId());
        applicationContext.publishEvent(spaceUpdateEvent);

        return ResultJson.success(room.getId());
    }

    @Override
    @Transactional
    public ResultJson update(RoomDTO roomDTO) {
        Room room = new Room();
        BeanUtils.copyProperties(roomDTO, room);
        Room old = roomDao.selectById(room.getId());
        Organization organization = organizationDao.selectById(old.getOrganizationId());
        organization.setName(room.getName());
        organization.setSortField(room.getSortField());
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(room.getCode())) {
            organization.setCode(room.getCode());
        }
        if (null !=room.getFunctionType()){
            organization.setFunctionType(room.getFunctionType());
        }
        if (null != old.getSortField() && !old.getSortField().equals(roomDTO.getSortField())){
            List<Organization> organizationList = organizationService.list(new OrganizationQuery().withParentId(organization.getParentId()));
            List<Integer> orgIds = organizationList.stream().filter(i->null != i.getSortField()).map(Organization::getId).collect(Collectors.toList());
            UpdateWrapper<Room> updateWrapper = new UpdateWrapper<>();
            updateWrapper.in("organization_id",orgIds);
            UpdateWrapper<Organization> organizationUpdateWrapper = new UpdateWrapper<>();
            organizationUpdateWrapper.in("id",orgIds);
            if (old.getSortField() > roomDTO.getSortField()){
                //大改小 小于等于'大'并且大于等于'小'的加1
                updateWrapper.ge("sort_field",roomDTO.getSortField());
                updateWrapper.le("sort_field",old.getSortField());
                organizationUpdateWrapper.ge("sort_field",roomDTO.getSortField());
                organizationUpdateWrapper.le("sort_field",old.getSortField());
                updateWrapper.setSql("sort_field = sort_field+1");
                organizationUpdateWrapper.setSql("sort_field = sort_field+1");
           }else {
                //小改大 大于'小'并且小于等于'大'的减1
                updateWrapper.le("sort_field",roomDTO.getSortField());
                updateWrapper.gt("sort_field",old.getSortField());
                organizationUpdateWrapper.le("sort_field",roomDTO.getSortField());
                organizationUpdateWrapper.gt("sort_field",old.getSortField());
                updateWrapper.setSql("sort_field = sort_field-1");
                organizationUpdateWrapper.setSql("sort_field = sort_field-1");
            }
            this.update(updateWrapper);
            organizationService.update(organizationUpdateWrapper);
        }
        ResultJson update = organizationService.update(organization);
        if (!update.getState()) {
            return update;
        }
        roomDao.updateById(room);
        if (null == organization) {
            throw new DataException("数据错误");
        }

        RoomDTO roomDTO1 = new RoomDTO();
        BeanUtils.copyProperties(room, roomDTO1);
        roomDTO1.setFullName(getFullName(room.getOrganizationId()));
        AbstractSpace space = roomDTO1;
        space.setSpaceType(OrganizationTypeEnum.ROOM);
        SpaceUpdateEvent spaceUpdateEvent = new SpaceUpdateEvent(this, space, organization.getProjectId());
        applicationContext.publishEvent(spaceUpdateEvent);
        return ResultJson.success();
    }

    @Override
    @Transactional
    public ResultJson delete(Integer id, Account account) {

        Room room = roomDao.selectById(id);
        if (null == room) {
            return ResultJson.fail("数据不存在");
        }
        Room notification = room;
        Boolean aBoolean = organizationService.hasChild(room.getOrganizationId());
        if (aBoolean) {
            return ResultJson.fail("存在下级无法删除");
        }
        roomDao.deleteById(id);
        Organization organization = organizationService.getById(notification.getOrganizationId());
        organizationDao.deleteById(room.getOrganizationId());
        organizationProducer.deletePush(JSON.toJSONString(Collections.singleton(organization)));
        AbstractSpace space = notification;
        space.setSpaceType(OrganizationTypeEnum.ROOM);
        SpaceUpdateEvent spaceUpdateEvent = new SpaceUpdateEvent(this, space, organization.getProjectId());
        applicationContext.publishEvent(spaceUpdateEvent);
        return ResultJson.success("操作成功");
    }

    /**
     * 查询完全路径名
     *
     * @param orgId
     * @return
     */
    private String getFullName(Integer orgId) {
        OrganizationQuery organizationQuery = new OrganizationQuery();
        organizationQuery.withId(orgId);

        QueryWrapper<OrganizationType> organizationTypeQueryWrapper = new QueryWrapper<>();
        organizationTypeQueryWrapper.select("id");
        organizationTypeQueryWrapper.in("view_type", Arrays.asList(ViewType.SPACE.id, ViewType.SPACE_DEFINED.id));
        List<OrganizationType> list = organizationTypeService.list(organizationTypeQueryWrapper);
        organizationQuery.withTypes(list.stream().map(l -> l.getId()).collect(Collectors.toList()));
        return organizationService.fullName(organizationQuery);
    }

    @Override
    public Page<Room> page(RoomQuery roomQuery, Account account, Page page) {

        return roomDao.page(page, roomQuery);
    }

    @Override
    public List<Room> list(RoomQuery roomQuery) {
        return roomDao.list(roomQuery);
    }

    @Override
    public Room one(RoomQuery roomQuery) {
        if (null != roomQuery) {
            QueryWrapper<Room> queryWrapper = new QueryWrapper<>();
            if (null != roomQuery.id) {
                queryWrapper.eq("id", roomQuery.id);
            }
            if (null != roomQuery.orgId) {
                queryWrapper.eq("organization_id", roomQuery.orgId);
            }
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(roomQuery.code)) {
                queryWrapper.eq("code", roomQuery.code);
            }
            queryWrapper.eq("is_deleted", false);
            return roomDao.selectOne(queryWrapper);
        }
        return null;
    }

    @Override
    public Room detailByCode(String code) {
        return roomDao.selectOne(new QueryWrapper<Room>().eq("code", code));
    }

    @Override
    @Transactional
    public ResultJson batchCreate(List<RoomDTO> rooms) {
        IRoomService bean = applicationContext.getBean(IRoomService.class);
        for (RoomDTO room : rooms) {
            bean.create(room);
        }
        return ResultJson.success();
    }

    /**
     * 新增组织（cent_sdata.sdata_organization）数据+房间(cent_sdata.sdata_room)数据
     *
     * @param roomDTOS
     * @return
     */
    @Override
    @Transactional
    public ResultJson<List> batchCreateFaster(List<RoomDTO> roomDTOS) {

        if (CollectionUtils.isEmpty(roomDTOS)) {
            return ResultJson.fail("无效的数据");
        }

        List<ErrorSpace> errors = new ArrayList<>();
        // 数据处理 1 分组 2 校验
        Set<Integer> collect = roomDTOS.stream().map(i -> i.getParentId()).collect(Collectors.toSet());
        Map<Integer, List<RoomDTO>> parentAndChildMap = new HashMap<>();
        for (Integer i : collect) {
            parentAndChildMap.put(i, roomDTOS.stream().filter(j -> i.equals(j.getParentId())).collect(Collectors.toList()));
        }
        for (Map.Entry<Integer, List<RoomDTO>> entry : parentAndChildMap.entrySet()) {
            Integer parentId = entry.getKey();
            Organization organization = organizationDao.selectById(parentId);

            // 上级信息校验
            if (null == organization) {
                for (RoomDTO roomDTO : entry.getValue()) {
                    ErrorSpace errorSpace = new ErrorSpace();
                    errorSpace.setReason("上级信息不存在");
                    errorSpace.setObj(roomDTO);
                    errors.add(errorSpace);
                }
                continue;
            }

            // 名称校验
            List<RoomDTO> value = entry.getValue();
            Map<String, RoomDTO> map = new HashMap<>();
            Map<String, RoomDTO> roomDB = new HashMap<>();
            QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
            organizationQueryWrapper.select("name");
            organizationQueryWrapper.eq("parent_id", entry.getKey());
            List<Organization> rooms = organizationDao.selectList(organizationQueryWrapper);
            if (!rooms.isEmpty()) {
                for (Organization room : rooms) {
                    roomDB.put(room.getName(), null);
                }
            }
            for (RoomDTO roomDTO : value) {
                if (roomDB.containsKey(roomDTO.getName()) || map.containsKey(roomDTO.getName())) {
                    ErrorSpace errorSpace = new ErrorSpace();
                    errorSpace.setReason("名称重复");
                    errorSpace.setObj(roomDTO);
                    errors.add(errorSpace);
                } else {
                    map.put(roomDTO.getName(), roomDTO);
                }
            }
            List<Room> correctList = new ArrayList<>();
            for (Map.Entry<String, RoomDTO> entry1 : map.entrySet()) {
                correctList.add(entry1.getValue());
            }

            // code 校验
            Map<String, Room> codeMap = new HashMap<>();
            Map<String, Object> codeMapDB = new HashMap<>();
            // 这里仅校验同一个项目下的编码重复
            QueryWrapper<Organization> organizationQueryWrapper1 = new QueryWrapper<>();
            organizationQueryWrapper1.select("code");
            organizationQueryWrapper1.eq("project_id", organization.getProjectId());
            organizationQueryWrapper1.eq("type", OrganizationTypeEnum.ROOM.id);
            List<Organization> organizations1 = organizationDao.selectList(organizationQueryWrapper1);
            if (!organizations1.isEmpty()) {
                codeMapDB = organizations1.stream().collect(Collectors.toMap(Organization::getCode, Organization::getCode, (key1, key2) -> key1));
            }
            for (Room roomDTO : correctList) {
                ResultJson check = RoomCheck.check(roomDTO);
                if(!check.getState()){
                    ErrorSpace errorSpace = new ErrorSpace();
                    errorSpace.setReason(check.getMessage());
                    errorSpace.setObj(roomDTO);
                    errors.add(errorSpace);
                }else if (!StringUtils.isEmpty(roomDTO.getCode()) && (codeMapDB.containsKey(roomDTO.getCode()) || codeMap.containsKey(roomDTO.getCode()))) {
                    ErrorSpace errorSpace = new ErrorSpace();
                    errorSpace.setReason("编码重复");
                    errorSpace.setObj(roomDTO);
                    errors.add(errorSpace);
                } else {
                    if(StringUtils.isEmpty(roomDTO.getCode())){
                        roomDTO.setCode(UUID.randomUUID().toString().replaceAll("-", ""));
                    }
                    roomDTO.setIsDelete(false);
                    codeMap.put(roomDTO.getName(), roomDTO);
                }
            }
            correctList = correctList.stream().filter(i -> codeMap.containsKey(i.getName())).collect(Collectors.toList());

            if (correctList.isEmpty()) {
                log.info("校验后没有合适的数据");
                continue;
            }
            try {
                this.saveBatch(correctList);
            } catch (Exception e) {
                log.error("批量保存房间失败 {}", e.getMessage());
                for (Room room : correctList) {
                    ErrorSpace errorSpace = new ErrorSpace();
                    errorSpace.setReason("批量保存失败");
                    errorSpace.setObj(room);
                    errors.add(errorSpace);
                }
                continue;
            }
            // 保存组织信息
            List<Organization> organizations = new ArrayList<>();
            for (Room room : correctList) {
                Organization organization1 = new Organization();
                organization1.setName(room.getName());
                organization1.setParentId(room.getParentId());
                if (StringUtils.isEmpty(room.getCode())) {
                    String code = AutoCodeUtils.codeFormat(CodePrefixConstant.ROOM_PREFIX, room.getId(), CodePrefixConstant.CODE_LENGTH);
                    room.setCode(code);
                }
                organization1.setCode(room.getCode());
                organization1.setType(OrganizationTypeEnum.ROOM.id.intValue());
                organization1.setLevel(organization.getLevel() + 1);
                organization1.setIndustryId(organization.getIndustryId());
                organization1.setEnterpriseId(organization.getEnterpriseId());
                if (null != organization.getProjectId()) {
                    organization1.setProjectId(organization.getProjectId());
                }
                organizations.add(organization1);
            }
            organizationService.saveBatch(organizations);

            // 统一分组下名称不会重复
            Map<String, Integer> collect1 = organizations.stream().collect(Collectors.toMap(Organization::getName, Organization::getId));

            for (Room room : correctList) {
                room.setOrganizationId(collect1.get(room.getName()));
            }
            this.updateBatchById(correctList);
        }
        return ResultJson.success(errors);
    }

    @Override
    public Page<RentRoomPicDTO> rentRoomPicPage(RoomQuery roomQuery, Page page) {
        if (null == roomQuery.getParentId()) {
            log.info("参数错误");
            return page;
        }
        Organization parent = organizationService.getById(roomQuery.getParentId());
        if (null == parent) {
            log.info("上级不存在");
            return page;
        }
        // 分页查询下一级
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.eq("parent_id", roomQuery.getParentId());
        Page<Organization> page1 = organizationDao.selectPage(page, organizationQueryWrapper);

        List<Organization> records = page1.getRecords();
        if (CollectionUtils.isNotEmpty(records)) {
            List<RentRoomPicDTO> result = new ArrayList<>(records.size());
            OrganizationQuery organizationQuery = new OrganizationQuery();
            organizationQuery.setIds(records.stream().map(i -> i.getId()).collect(Collectors.toList()));
            List<Organization> child = organizationService.child(organizationQuery);
            if (child.isEmpty()) {
                log.info("没有房间数据");
                return page;
            }

            // 获取下房间
            List<Organization> roomNodes = child.stream().filter(i -> i.getType().intValue() == OrganizationTypeEnum.ROOM.id.intValue()).collect(Collectors.toList());
            if (roomNodes.isEmpty()) {
                log.info("暂无匹配的房间数据");
                return page;
            }

            //判断当前选择的是房间上面一级还是上面两级，如果currLevel == lowLevel则表示选择的为房间上一级，需要过滤掉不是房间的空间类型
            Integer currLevel = records.get(0).getLevel();
            List<Organization> sortLevel = roomNodes.stream().sorted(Comparator.comparing(Organization::getLevel).reversed()).collect(Collectors.toList());
            Integer lowLevel = sortLevel.get(0).getLevel();
            // 如果当前选择的是房间上面一级（当前展示应为所有房间）
            if (currLevel.equals(lowLevel)) {
                records = records.stream().filter(i -> i.getType() == OrganizationTypeEnum.ROOM.id.intValue()).collect(Collectors.toList());
            }

            roomQuery.setOrgIds(roomNodes.stream().map(i -> i.getId()).collect(Collectors.toList()));
            List<Room> rooms = baseMapper.roomPicList(roomQuery);
            Map<Integer, Room> roomMap = rooms.stream().collect(Collectors.toMap(Room::getOrganizationId, Function.identity()));
            Map<Integer, List<Room>> parentIdRoomMap = new HashMap<>();
            for (Organization roomNode : roomNodes) {
                List<Room> rooms1 = parentIdRoomMap.get(roomNode.getParentId());
                if (CollectionUtils.isEmpty(rooms1)) {
                    List<Room> childRoom = new ArrayList<>();
                    Room room = roomMap.get(roomNode.getId());
                    if (null != room) {
                        childRoom.add(room);
                        parentIdRoomMap.put(roomNode.getParentId(), childRoom);
                    }
                } else {
                    Room room = roomMap.get(roomNode.getId());
                    if (null != room) {
                        rooms1.add(room);
                    }
                }
            }
            for (Organization record : records) {
                RentRoomPicDTO rentRoomPicDTO = new RentRoomPicDTO();
                BeanUtils.copyProperties(record, rentRoomPicDTO);
                // 获取下级的房间 设置下级
                List<Room> rooms1 = parentIdRoomMap.get(rentRoomPicDTO.getId());
                if (CollectionUtils.isNotEmpty(rooms1)) {
                    List<RoomCompanyDTO> roomCompanyDTOS = rooms1.stream().map(i -> {
                        RoomCompanyDTO roomCompanyDTO = new RoomCompanyDTO();
                        BeanUtils.copyProperties(i, roomCompanyDTO);
                        return roomCompanyDTO;
                    }).collect(Collectors.toList());
                    rentRoomPicDTO.setChild(roomCompanyDTOS);
                } else {
                    rentRoomPicDTO.setChild(Collections.emptyList());
                }
                // 当倒数第二层级是房间 并且没有下级的时候才按照房间来看待变成房间列表
                if (OrganizationTypeEnum.ROOM.id.intValue() == record.getType() && CollectionUtils.isEmpty(rentRoomPicDTO.getChild())) {
                    Room room = roomMap.get(record.getId());
                    if (null != room) {
                        rentRoomPicDTO.setRoomStatus(room.getStatus());
                        rentRoomPicDTO.setArea(room.getArea());
                        rentRoomPicDTO.setOrganizationId(room.getOrganizationId());
                        result.add(rentRoomPicDTO);
                    }
                } else {
                    result.add(rentRoomPicDTO);
                }
            }
            page.setRecords(result);
        }
        return page;
    }


    @Override
    public ResultJson roomTypeProportionStatistics(Short industryId, List<Integer> orgIds) {
        OrganizationQuery organizationQuery = new OrganizationQuery();
        organizationQuery.withIds(orgIds);
        // 获取当前组织子集
        List<Organization> child = organizationService.child(organizationQuery);
        if (child.isEmpty()) {
            return ResultJson.fail("参数错误");
        }
        List<Integer> roomIds = child.stream().filter(i -> i.getType() == OrganizationTypeEnum.ROOM.id.intValue()).map(i -> i.getId()).collect(Collectors.toList());
        // 获取房间总面积
        BigDecimal totalArea = roomDao.totalroomArea(roomIds);
        // 按类型统计面积集合
        List<RoomTypeArea> typeAreaList = roomDao.roomAreaByType(roomIds);
        // 类型统计
        ArrayList<RoomTypeArea> resultList = new ArrayList<>();
        // 返回前端对象
        RoomAreaCountDTO result = new RoomAreaCountDTO();
        for (RoomTypeArea roomTypeArea : typeAreaList) {
            roomTypeArea.setTypeName(RoomTypeEnum.getDescription(roomTypeArea.getType()));
            if (null != roomTypeArea.getArea()) {
                BigDecimal rate = null;
                rate = roomTypeArea.getArea().divide(totalArea, 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
                // 去除小数点
                roomTypeArea.setProportion(rate.setScale(0, 0));
            } else {
                roomTypeArea.setProportion(new BigDecimal(0));
            }
            resultList.add(roomTypeArea);
        }
        result.setTotalRoomArea(totalArea);
        result.setStatistics(resultList);
        return ResultJson.success(result);
    }


    @Override
    public ResultJson getRoomCountByType(RoomQuery roomQuery) {
        if (null == roomQuery.getProjectId()) {
            return ResultJson.fail("参数有误");
        }
        Project project = projectService.findById(roomQuery.getProjectId());
        if (null == project) {
            return ResultJson.fail("该项目不存在");
        }
        // 查找组织表type为房间（6）的数据
        QueryWrapper<Organization> orgQueryWarpper = new QueryWrapper<>();
        orgQueryWarpper.eq("is_deleted", 0);
        orgQueryWarpper.in("type", roomQuery.getTypes());
        orgQueryWarpper.eq("project_id", roomQuery.getProjectId());
        List<Organization> orgList = organizationService.list(orgQueryWarpper);
        roomQuery.setOrgIds(orgList.stream().map(o -> o.getId()).collect(Collectors.toList()));
        List<RoomTypeCount> list = roomDao.roomCountByTypeCount(roomQuery);
        return ResultJson.success(list);
    }

    @Override
    public String getCurrentCode() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    @Override
    @Transactional
    public ResultJson split(RoomOperateDTO roomOperateDTO) {
        if(CollectionUtils.isEmpty(roomOperateDTO.getIds())){
            return ResultJson.fail("缺少id");
        }
        if(CollectionUtils.isEmpty(roomOperateDTO.getRooms())){
            return ResultJson.fail("缺少房间数据");
        }
        if(roomOperateDTO.getRooms().size() < 2){
            return ResultJson.fail("房间数量错误");
        }
        RoomQuery roomQuery = new RoomQuery();
        roomQuery.setId(roomOperateDTO.getIds().get(0));
        Room room = this.one(roomQuery);
        if(null == room){
            return ResultJson.fail("房间不存在");
        }

        Organization organization = organizationService.getById(room.getOrganizationId());

        delete(roomOperateDTO.getIds().get(0), null);
        List<RoomDTO> rooms = roomOperateDTO.getRooms();
        for (RoomDTO roomDTO : rooms) {
            roomDTO.setParentId(organization.getParentId());
            roomDTO.setSortField(room.getSortField());
            if(StringUtils.isEmpty(roomDTO.getCode())){
                roomDTO.setCode(getCurrentCode());
            }
        }
        batchCreate(rooms);
        delete(room.getId(), null);
        // 记录拆分日志
        RoomDTO roomDTO = new RoomDTO();
        BeanUtils.copyProperties(room, roomDTO);
        roomOperateDTO.setOld(Arrays.asList(roomDTO));
        roomOperateDTO.setRooms(rooms);
        saveLog(roomOperateDTO, 2);

        return ResultJson.success();
    }

    /**
     * 拆分合并记录
     * @param roomOperateDTO
     * @param type
     */
    public void saveLog(RoomOperateDTO roomOperateDTO, Integer type){
        // 拆分
        if(2 == type){
            List<RoomOperateLog> roomOperateLogs = new ArrayList<>();
            for (RoomDTO room : roomOperateDTO.getRooms()) {
                RoomOperateLog roomOperateLog = new RoomOperateLog();
                roomOperateLog.setOldRoomId(roomOperateDTO.getIds().get(0));
                roomOperateLog.setName(roomOperateDTO.getOld().get(0).getName());
                roomOperateLog.setCode(roomOperateDTO.getOld().get(0).getCode());
                roomOperateLog.setType(2);
                roomOperateLog.setNewRoomId(room.getId());
                roomOperateLogs.add(roomOperateLog);
            }
            roomOperatorLogService.saveBatch(roomOperateLogs);
        }
        // 合并
        if(1 == type){
            List<RoomOperateLog> roomOperateLogs = new ArrayList<>();
            for (Room room : roomOperateDTO.getOld()) {
                RoomOperateLog roomOperateLog = new RoomOperateLog();
                roomOperateLog.setOldRoomId(room.getId());
                roomOperateLog.setNewRoomId(roomOperateDTO.getRooms().get(0).getId());
                roomOperateLog.setName(room.getName());
                roomOperateLog.setCode(room.getCode());
                roomOperateLog.setType(1);
                roomOperateLogs.add(roomOperateLog);
            }
            roomOperatorLogService.saveBatch(roomOperateLogs);
        }
    }

    @Override
    public ResultJson merge(RoomOperateDTO roomOperateDTO) {
        if(CollectionUtils.isEmpty(roomOperateDTO.getIds())){
            return ResultJson.fail("缺少id");
        }
        if(2 > roomOperateDTO.getIds().size()){
            return ResultJson.fail("id参数错误");
        }
        if(CollectionUtils.isEmpty(roomOperateDTO.getRooms())){
            return ResultJson.fail("合并房间参数错误");
        }

        //查询一个被合并的房间
        List<Room> rooms = this.listByIds(roomOperateDTO.getIds());
        if(CollectionUtils.isEmpty(rooms)){
            return ResultJson.fail("房间不存在");
        }
        List<RoomDTO> roomDTOS = new ArrayList<>();
        for (Room room : rooms) {
            RoomDTO roomDTO = new RoomDTO();
            BeanUtils.copyProperties(room, roomDTO);
            roomDTOS.add(roomDTO);
        }
        roomOperateDTO.setOld(roomDTOS);
        // 合并的房间
        RoomDTO room = roomOperateDTO.getRooms().get(0);
        if(StringUtils.isEmpty(room.getCode())){
            room.setCode(getCurrentCode());
        }
        Organization org = organizationService.getById(rooms.get(0).getOrganizationId());
        room.setParentId(org.getParentId());
        Room old = roomDao.selectById(roomOperateDTO.getOperateId());
        room.setSortField(old.getSortField());
        room.setIsDelete(false);
        for (Integer id : roomOperateDTO.getIds()) {
            delete(id, null);
        }
        IRoomService bean = applicationContext.getBean(IRoomService.class);
        ResultJson resultJson = bean.create(room);
        room.setId((Integer) resultJson.getResult());
        roomOperateDTO.setRooms(Arrays.asList(room));
        saveLog(roomOperateDTO, 1);
        return ResultJson.success();
    }

    @Override
    public ResultJson refreshSort(RoomQuery roomQuery) {
        List<Room> rooms = this.list(roomQuery);
        List<Organization> organizationList = organizationService.list(new OrganizationQuery().withIds(rooms.stream().map(Room::getOrganizationId).collect(Collectors.toList())));
        organizationList = organizationList.stream().distinct().collect(Collectors.toList());
        Map<Integer,Organization> organizationMap = organizationList.stream().collect(Collectors.toMap(Organization::getId, Function.identity()));
//        List<List<Area>> parts = Lists.partition(areas, 500);
        for (int i = 0; i < rooms.size(); i++) {
            rooms.get(i).setSortField(i+1);
            JSONObject jsonObject = JSONObject.parseObject(rooms.get(i).getExpand());
            if (null != jsonObject){
                jsonObject.put("sortField",i+1);
                rooms.get(i).setExpand(jsonObject.toJSONString());
            }
            organizationMap.get(rooms.get(i).getOrganizationId()).setSortField(i+1);
        }
        this.updateBatchById(rooms);
        organizationService.updateBatchById(organizationMap.values());
        return ResultJson.success("刷新成功");
    }

    private void parameterHandler(RoomQuery roomQuery, QueryWrapper<Room> queryWrapper) {
        if (null != roomQuery) {
            if (StringUtils.isNotEmpty(roomQuery.keywords)) {
                queryWrapper.like("name", roomQuery.keywords);
            }
            if (null != roomQuery.orgId) {
                queryWrapper.eq("organization_id", roomQuery.orgId);
            }
            if (null != roomQuery.id) {
                queryWrapper.eq("id", roomQuery.id);
            }
            if (CollectionUtils.isNotEmpty(roomQuery.ids)) {
                queryWrapper.in("id", roomQuery.ids);
            }
            if (CollectionUtils.isNotEmpty(roomQuery.orgIds)) {
                queryWrapper.in("organization_id", roomQuery.orgIds);
            }
            if (null != roomQuery.parentId) {
                QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
                organizationQueryWrapper.eq("parent_id", roomQuery.parentId);
                List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper);
                if (!organizations.isEmpty()) {
                    queryWrapper.in("organization_id", organizations.stream().map(o -> o.getId()).collect(Collectors.toList()));
                } else {
                    queryWrapper.eq("organization_id", -1);
                }
            } else if (null != roomQuery.floorId) {
                QueryWrapper<Floor> floorQueryWrapper = new QueryWrapper<>();
                queryWrapper.eq("id", roomQuery.floorId);
                List<Floor> floors = floorDao.selectList(floorQueryWrapper);
                if (!floors.isEmpty()) {
                    Floor floor = floors.get(0);
                    QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
                    organizationQueryWrapper.eq("parent_id", floor.getOrganizationId());
                    List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper);
                    if (!organizations.isEmpty()) {
                        queryWrapper.in("organization_id", organizations.stream().map(o -> o.getId()).collect(Collectors.toList()));
                    } else {
                        queryWrapper.eq("organization_id", -1);
                    }
                }
            }
        }
    }


    /**
     * 通过编码列表获取房间信息
     */
    @Override
    public List<Room> detailByCodes(List<String> codes) {
        System.out.println("codes = " + codes);
        return roomDao.selectList(new QueryWrapper<Room>().in("code", codes));
    }

}
